package message

import (
	"encoding/binary"
	"gitee.com/zhongguo168a/go-nodex/nodex/enums/Serialize"
	"gitee.com/zhongguo168a/gocodes/datax"
	"gitee.com/zhongguo168a/gocodes/datax/binaryx"
	"gitee.com/zhongguo168a/gocodes/myx/errorx"
	"io"
)

// 协议相应消息
type ResponseMessage struct {
	//
	Seq uint32
	//
	Route string //消息的ID
	//
	SerializeMode Serialize.Mode
	// 0-失败 1-成功
	Error string
	//
	Data []byte //消息的内容
}

func (msg *ResponseMessage) PackageLen() int {
	// PushTag + Seq + SerializeMode + Error + Rows
	return 1 + 4 + 1 + (2 + len(msg.Error)) + (2 + len(msg.Data))
}

func (msg *ResponseMessage) Unpack(reader io.Reader) (err error) {
	err = binary.Read(reader, binary.LittleEndian, &msg.Seq)
	if err != nil {
		err = errorx.Wrap(err, "Read Seq")
		return
	}
	err = binary.Read(reader, binary.LittleEndian, &msg.SerializeMode)
	if err != nil {
		err = errorx.Wrap(err, "Read SerializeMode")
		return
	}
	if data, err := binaryx.ReadUTF(reader, binary.LittleEndian); err != nil {
		return errorx.Wrap(err, "read Error")
	} else {
		msg.Error = data
	}
	if data, err := binaryx.ReadBytes(reader, binary.LittleEndian); err != nil {
		return errorx.Wrap(err, "read Rows")
	} else {
		msg.Data = data
	}
	return
}

// Pack 封包方法(压缩数据)
func (msg *ResponseMessage) Pack(writer io.Writer) error {
	// tag data
	if err := binary.Write(writer, binary.LittleEndian, uint16(msg.PackageLen())); err != nil {
		return errorx.Wrap(err, "write PackageLen", datax.M{"PackageLen": msg.PackageLen()})
	}
	// tag data
	if err := binary.Write(writer, binary.LittleEndian, int8(PushTag_Response)); err != nil {
		return errorx.Wrap(err, "write PushTag_Response", datax.M{"PushTag_Response": PushTag_Response})
	}

	if err := binary.Write(writer, binary.LittleEndian, msg.Seq); err != nil {
		return errorx.Wrap(err, "write Seq", datax.M{"Seq": msg.Seq})
	}
	if err := binary.Write(writer, binary.LittleEndian, msg.SerializeMode); err != nil {
		return errorx.Wrap(err, "write SerializeMode", datax.M{"SerializeMode": msg.SerializeMode})
	}
	if err := binaryx.WriteUTF(writer, binary.LittleEndian, msg.Error); err != nil {
		return errorx.Wrap(err, "write Error", datax.M{"Error": msg.Route})
	}
	if err := binaryx.WriteBytes(writer, binary.LittleEndian, msg.Data); err != nil {
		return errorx.Wrap(err, "write Rows", datax.M{"Rows": msg.Data})
	}
	return nil
}
